﻿using System;
using System.Web;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TSharp.Core.TestUtil;
using TSharp.Core.Util.TypeConvert;
using Common.Logging;

namespace TSharp.Core.AppBox.Tests
{
    /// <summary>
    ///     这是 TypeFactoryTest 的测试类，旨在
    ///     包含所有 TypeFactoryTest 单元测试
    /// </summary>
    [TestClass]
    public class TypeFactoryTest
    {
        public enum enumByte : byte
        {
            a,
            b,
            c,
            d
        }

        public enum enumInt
        {
            a,
            b,
            c,
            d
        }

        private static HttpContextBase context = TestHelper.FakeHttpContext().Object;

        private static ILog log = LogManager.GetLogger("Test");

        /// <summary>
        ///     获取或设置测试上下文，上下文提供
        ///     有关当前测试运行及其功能的信息。
        /// </summary>
        public TestContext TestContext { get; set; }

        #region 附加测试特性

        // 
        //编写测试时，还可使用以下特性:
        //
        //使用 ClassInitialize 在运行类中的第一个测试前先运行代码
        [ClassInitialize]
        public static void MyClassInitialize(TestContext testContext)
        {
            TestHelper.SetupTest();
        }

        //
        //使用 ClassCleanup 在运行完类中的所有测试后再运行代码
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //使用 TestInitialize 在运行每个测试前先运行代码
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //使用 TestCleanup 在运行完每个测试后运行代码
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //

        #endregion

        /// <summary>
        ///     JudgeType 的测试
        /// </summary>
        public void JudgeTypeTestHelper<TResult, TArg>()
        {
            int arg = 99; // TODO: 初始化为适当的值
            var judicative = new MyJudge();
            int? expected = 99;

            int? actual = TypeFactory.Detect(true, judicative, arg);

            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void JudgeTypeTest()
        {
            JudgeTypeTestHelper<GenericParameterHelper, GenericParameterHelper>();
        }


        /// <summary>
        ///     Detect 的测试
        /// </summary>
        [TestMethod]
        public void DetectTimeSpanTest()
        {
            //object detectorObj = TimeSpan.FromMilliseconds(33333); // TODO: 初始化为适当的值
            //TimeSpan defaultValue = new TimeSpan(); // TODO: 初始化为适当的值

            //TimeSpan expected = TimeSpan.FromMilliseconds(33333);
            //TimeSpan actual;
            //actual = TypeFactory.Detect(detectorObj, defaultValue);
            //Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void DetectGuidSpanTest()
        {
            //object detectorObj = Guid.NewGuid(); // TODO: 初始化为适当的值
            //Guid defaultValue = new Guid(); // TODO: 初始化为适当的值

            //Guid expected = (Guid)detectorObj;
            //Guid actual;
            //actual = TypeFactory.Detect(detectorObj, defaultValue);
            //Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void DetectEnumSpanTest()
        {
            TestHelper.LadderLogicTest(() =>
                {
                    object detectorObj = enumInt.c;
                    var defaultValue = enumInt.b; // TODO: 初始化为适当的值

                    var expected = enumInt.c;
                    enumInt? actual = TypeFactory.ToNullableEnum<enumInt>(detectorObj, defaultValue);

                    //  Console.WriteLine(actual.ToString());


                    Assert.AreEqual(expected, actual);

                    enumByte? actual1 = TypeFactory.ToNullableEnum<enumByte>(detectorObj, enumByte.b);

                    Assert.AreEqual(enumByte.c, actual1);
                }
                );
        }

        [TestMethod]
        public void AopContextTest()
        {
            AopContext.SetHttpContextFactory(() => WindowContext.Instance);

            TestHelper.MultiThreadLadderLogicTest(() =>
                {
                    IServiceLocator s = AopContext.GetDefaultLactor();
                    //if (!Object.ReferenceEquals(AopContext.Context.Application, context.Application))
                    //{
                    //    Console.WriteLine("False");
                    //}
                    // log.Info("测试");
                });
        }


        [TestMethod]
        public void TestAopType()
        {
            for (int i = 0, n = 500000; i < n; i++)
                TypeFactory.ToFormatString(TimeSpan.FromTicks(new Random().Next(int.MaxValue)));
        }

        [TestMethod]
        public void TestTemp()
        {
            int? a = 3;
            a = null;
            Console.WriteLine(a == null);
            Console.WriteLine(a.HasValue);
        }

        public class MyJudge : TypeDetector<int?, int>
        {
            /// <summary>
            ///     判断对象为null，空引用。
            /// </summary>
            /// <param name="judgeObj">The judge obj.</param>
            /// <param name="arg">The arg.</param>
            /// <returns></returns>
            public override int? Empty(object judgeObj, int arg)
            {
                return null;
            }

            /// <summary>
            ///     简单类型，表示 true 或 false 的布尔值。
            /// </summary>
            /// <param name="judgeObj">
            ///     if set to <c>true</c> [judge obj].
            /// </param>
            /// <param name="arg">The arg.</param>
            /// <returns></returns>
            public override int? Boolean(Boolean judgeObj, int arg)
            {
                return judgeObj ? 1 : 0;
            }

            /// <summary>
            ///     整型，表示值介于 -32768 到 32767 之间的有符号 16 位整数。
            /// </summary>
            /// <param name="judgeObj">The judge obj.</param>
            /// <param name="arg">The arg.</param>
            /// <returns></returns>
            public override int? Int16(short judgeObj, int arg)
            {
                return judgeObj;
            }

            /// <summary>
            ///     整型，表示值介于 -2147483648 到 2147483647 之间的有符号 32 位整数。
            /// </summary>
            /// <param name="judgeObj">The judge obj.</param>
            /// <param name="arg">The arg.</param>
            /// <returns></returns>
            public override int? Int32(int judgeObj, int arg)
            {
                return judgeObj;
            }

            /// <summary>
            ///     整型，表示值介于 0 到 255 之间的无符号 8 位整数。
            /// </summary>
            /// <param name="judgeObj">The judge obj.</param>
            /// <param name="arg">The arg.</param>
            /// <returns></returns>
            public override int? Byte(byte judgeObj, int arg)
            {
                return judgeObj;
            }

            /// <summary>
            ///     整型，表示值介于 0 到 65535 之间的无符号 16 位整数。System.TypeCode.Char 类型的可能值集与 Unicode 字符集相对应。
            /// </summary>
            /// <param name="judgeObj">The judge obj.</param>
            /// <param name="arg">The arg.</param>
            /// <returns></returns>
            public override int? Char(char judgeObj, int arg)
            {
                return judgeObj;
            }
        }
    }
}